# -*- coding: utf-8 -*-
'''
Created on 31/01/2010

@author: joger
'''

import os
import pexpect
import sys
import re
from shutil import rmtree
from gnupg024 import gnupg


from comun import mensageError as msje, mensageAlerta as msja, mensajePregunta as msjp, validarNombreFichero, validarClave

class Modelo():
    '''
    classdocs
    '''

    def __init__(self,controlador):
        '''
        Constructor
        '''
        
        self.controlador = controlador
        self.gpg = gnupg.GPG(gnupghome=self.controlador.rutaGpg)
    
    def listarUnidades(self):
        
        unidades = []
        
        carpeta = self.controlador.rutaTibisay + self.controlador.unidades
        directorios = [d for d in os.listdir(carpeta) if os.path.isdir(os.path.join(carpeta, d)) and d[0] != "."]
        
        for u in directorios:
            unidades.append(u)
        
        return unidades
    
    def crearUnidad(self,nombre,clave):
        
        
        #Procedemos a crear los directorios
        os.mkdir(self.controlador.rutaTibisay + self.controlador.unidades + "/" + nombre)
        os.mkdir(self.controlador.rutaTibisay + self.controlador.montaje + "/" + nombre)
        
        
        #Procedemos a crear la unidad
        try:
            #cmd = 'encfs ' + self.controlador.rutaTibisay + self.controlador.unidades + "/" + nombre + " " + self.controlador.rutaTibisay + self.controlador.montaje + "/" + nombre
            cmd = 'encfs "%s%s/%s" "%s%s/%s"' % (self.controlador.rutaTibisay,self.controlador.unidades,nombre,self.controlador.rutaTibisay,self.controlador.montaje,nombre)
            #print cmd
            
            proceso = pexpect.spawn(cmd)
            proceso.sendline("")
            proceso.expect('Nueva contraseña EncFS: ')
            proceso.sendline(clave)
            proceso.expect('Verifique la contraseña EncFS: ')
            proceso.sendline(clave)
            #Por alguna razón que desconozco este proceso se queda como colgado y monta la unidad de forma corrupta.
            #Al asignar otro spawn a la variable el proceso es liberado
            proceso = pexpect.spawn('encfsctl passwd ' + self.controlador.rutaTibisay + self.controlador.unidades + "/" + nombre)
            
        except:
            #f = open("/home/joger/Escritorio/a.txt","w")
            #f.write(str(sys.exc_info()[1]).encode("utf8"))
            self.controlador.vista.txtPanelC.SetLabel(str(proceso.before))
            msje(self.controlador.vista.ventanaHija,"¡Ocurrio un error inesperado! Lea la información en la parte inferior de la aplicación y consulte al administrador del sistema")
            return False
        
        return True
        
    def eliminarUnidad(self,unidad):
        
        try:
            #print self.controlador.rutaTibisay + self.controlador.unidades + "/" + unidad
            #print self.controlador.rutaTibisay + self.controlador.montaje + "/" + unidad
            rmtree(self.controlador.rutaTibisay + self.controlador.unidades + "/" + unidad)
            rmtree(self.controlador.rutaTibisay + self.controlador.montaje + "/" + unidad)
        except:
            self.controlador.vista.txtPanelC.SetLabel(str(sys.exc_info()[1]))
            return False
        
        return True
        
    
    def desmontarUnidad(self,unidad):
        
        #Procedemos a desmontar la unidad
        try:
            #cmd = 'fusermount -u ' + self.controlador.rutaTibisay + self.controlador.montaje + "/" + unidad
            cmd = 'fusermount -u "%s%s/%s"' % (self.controlador.rutaTibisay,self.controlador.montaje,unidad)
            os.system(cmd)
            
        except:
            self.controlador.vista.txtPanelC.SetLabel(str(proceso.after))
            msje(self.controlador.vista.ventanaHija,"¡Ocurrio un error al momento de querer desmontar la unidad! Lea la información en la parte inferior de la aplicación y consulte al administrador del sistema")
            return False
        
        return True

    
    def montarUnidad(self,unidad,clave):
        #print unidad,clave
        #Procedemos a montar la unidad
        try:
            #cmd = 'encfs --extpass="echo ' + clave + '" ' + self.controlador.rutaTibisay + self.controlador.unidades + "/" + unidad + " " + self.controlador.rutaTibisay + self.controlador.montaje + "/" + unidad
            flag = False
            fTmp = '/tmp/verificarPassword.tibisay'
            cmd = 'encfs --extpass=\'echo "%s"\' "%s%s/%s" "%s%s/%s" > %s' % (clave,self.controlador.rutaTibisay,self.controlador.unidades,unidad,self.controlador.rutaTibisay,self.controlador.montaje,unidad,fTmp)
            #print cmd
            os.system('%s' % cmd)
            f = open(fTmp,"r")
            lon = len(f.readlines())
            if lon > 0:
                flag = True
            f.close()
            os.remove(fTmp)
            if flag:
                self.controlador.vista.txtPanelC.SetLabel(u'¡Clave incorrecta! La unidad no será montada')
                msje(self.controlador.vista.ventanaHija,u'¡Clave incorrecta! La unidad no será montada')
                return False
            
            
            #print cmd
            #print 'Clave: %s' % clave
            #proceso = pexpect.spawn(cmd)
            #proceso.expect('Contraseña EncFS: ')
            #proceso.sendline(clave)
            #try:
            #    lineas = proceso.readlines()
            #    self.controlador.vista.txtPanelC.SetLabel(str(lineas[0]))
            #    msje(self.controlador.vista.ventanaHija,"La clave es incorrecta")
            #    return False
            #except:
            #    pass 
        except:
            
            self.controlador.vista.txtPanelC.SetLabel('Error al momento de montar la unidad: %s' % os.sys.exc_info()[1])
            msje(self.controlador.vista.ventanaHija,"¡Ocurrio un error inesperado! Lea la información en la parte inferior de la aplicación y consulte al administrador del sistema")
            return False
        
        return True


    def crearLlaves(self,nombre,
        correo,
        clave,
        tipo,
        longitud,
        comentario,
        subTipo,
        fecha):
        
        """
        print tipo.encode("utf-8")
        print longitud.encode('utf-8')
        print subTipo.encode("utf-8")
        print longitud.encode('utf-8')
        print fecha.encode('utf-8')
        print nombre.encode("utf-8")
        print correo.encode("utf-8")
        print clave.encode("utf-8")
        return True
        """
        
        
        params = {}
        params['Key-Type'] = tipo.encode("utf-8")
        params['Key-Length'] = longitud.encode('utf-8')
        params['Subkey-Type'] = subTipo.encode("utf-8")
        params['Subkey-Length'] = longitud.encode('utf-8')
        params['Expire-Date'] = fecha.encode('utf-8')
        params['Name-Real'] = nombre.encode("utf-8")
        params['Name-Email'] = correo.encode("utf-8")
        params['Passphrase'] = clave.encode("utf-8")
        if comentario:
            params['Name-Comment'] = comentario.encode("utf-8")
        else:
            params['Name-Comment'] = "Sin comentarios"
        
        #print params
        #return False
        
        input_key = self.gpg.gen_key_input(**params)        
        keys = self.gpg.gen_key(input_key)
        if keys:
            return True
        
        return False
    
    def listarLaves(self,tipo):
        
        public_keys = self.gpg.list_keys(tipo)
        l = []
        patron = re.compile(' \(|\) <')
        for pk in public_keys:
            l.append([pk['fingerprint'],patron.split(pk['uids'][1])[2][0:-1]])
            
        return l
